package recherche;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import tools.Normalizer;

public abstract class Modele {

	protected ArrayList<String> requete;
	protected ArrayList<String> requeteNorm;
	protected HashMap<String, HashMap<Integer, Double>> tfIdfMap;
	protected HashMap<String,String> result;



	public Modele(ArrayList<String> req){
		result = new HashMap<String,String>();
		this.requete = req;	
	}


	/**
	 * 
	 * @param req
	 * @param dfs
	 * @param urlTitle
	 * @return
	 */
	public abstract HashMap<String,String> execute(HashMap<String, HashMap<Integer, Integer>> dfs,

			HashMap<Integer,ArrayList<String>> urlTitle);

	/**
	 * Méthode qui calcule le tfidf de chaque mots (requete) par documents. 
	 * @return une map contenant pour chaque mots son tfidf par documents.
	 * @throws IOException
	 */
	public HashMap<String, HashMap<Integer, Double>> tfIdf(HashMap<Integer,ArrayList<String>> urlTitle, 
			HashMap<String, HashMap<Integer, Integer>> dfs){

		int documentNumber = urlTitle.size();	
		Integer tf;
		Integer df;
		Double tfIdf;
		tfIdfMap = new HashMap<String, HashMap<Integer,Double>>();
		HashMap<Integer, Double> listeTfIdfs;

		// Calcul des tf.idf
		// pour chaque mot de la requete
		for (String mot : requeteNorm) {
			HashMap<Integer, Integer> map = dfs.get(mot);
			if(map!=null){

				df = dfs.get(mot).size(); // nbre de doc qui contiennent "mot"
				listeTfIdfs = new HashMap<Integer, Double>();

				HashMap<Integer, Integer> docs = dfs.get(mot);
				//pour chaque document , chercher occurence
				for (Entry<Integer, Integer> doc : docs.entrySet()){
					tf = doc.getValue();//occurence du mot dans le doc
					tfIdf = (double)tf * Math.log10((double)documentNumber / (double)df);
					listeTfIdfs.put(doc.getKey(), tfIdf); //put (numero doc, poids)
				}
				tfIdfMap.put(mot, listeTfIdfs);	
			}
		}

		
		return tfIdfMap;
	}


	/**
	 * On ajoute la requete a dfs (map frequence) - on considère la requete comme un document. 
	 * 	La requete est à l'index -1, et l'occurence d'un mot dans une requete vaut toujorus 1
	 * @param urlTitle
	 * @param dfs
	 * @throws IOException 
	 */
	public void addRequeteMap(HashMap<Integer,ArrayList<String>> urlTitle, Normalizer norm, HashMap<String, HashMap<Integer, Integer>> dfs) throws IOException{

		requeteNorm = norm.normalize_req(requete, true);
		for(String mot : requeteNorm){
			if (dfs.get(mot) == null){
				HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
				map.put(-1, 1);
				dfs.put(mot,map);
			}
			else
				dfs.get(mot).put(-1, 1);
		}
	
		tfIdf(urlTitle, dfs);	
	}


}
